///////////////////////////////////////////////////////////////////////////////
//
// Utils.cpp
//
// Sample PokerStars/FullTilt online poker botting code. For more information:
//
// http://www.codingthewheel.com/archives/how-i-built-a-working-online-poker-bot-5
//
// DISCLAIMER OF WARRANTY 
//
// THIS SOURCE CODE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES AS TO PERFORMANCE
// OR MERCHANTABILITY. THE AUTHOR AND/OR DISTRIBUTORS OF THIS SOURCE CODE MAY
// HAVE MADE STATEMENTS ABOUT THIS SOURCE CODE. ANY SUCH STATEMENTS DO NOT 
// CONSTITUTE WARRANTIES AND SHALL NOT BE RELIED ON BY THE USER IN DECIDING 
// WHETHER TO USE THIS SOURCE CODE.
//
// THIS SOURCE CODE IS PROVIDED WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES
// WHATSOEVER. BECAUSE OF THE DIVERSITY OF CONDITIONS AND HARDWARE UNDER 
// WHICH THIS SOURCE CODE MAY BE USED, NO WARRANTY OF FITNESS FOR A PARTICULAR
// PURPOSE IS OFFERED. THE USER IS ADVISED TO TEST THE SOURCE CODE THOROUGHLY
// BEFORE RELYING ON IT. THE USER MUST ASSUME THE ENTIRE RISK OF USING THE
// SOURCE CODE.
//
///////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Utils.h"

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <string.h>
#include <psapi.h>
#include <strsafe.h>

#include <sddl.h>   // security descriptor stuff

#define BUFSIZE 512


// CreateMyDACL.
//    Create a security descriptor that contains the DACL 
//    you want.
//    This function uses SDDL to make Deny and Allow ACEs.
//
// Parameter:
//    SECURITY_ATTRIBUTES * pSA
//    Pointer to a SECURITY_ATTRIBUTES structure. It is your
//    responsibility to properly initialize the 
//    structure and to free the structure's 
//    lpSecurityDescriptor member when you have
//    finished using it. To free the structure's 
//    lpSecurityDescriptor member, call the 
//    LocalFree function.
// 
// Return value:
//    FALSE if the address to the structure is NULL. 
//    Otherwise, this function returns the value from the
//    ConvertStringSecurityDescriptorToSecurityDescriptor 
//    function.
BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
{
    // Define the SDDL for the DACL. This example sets 
    // the following access:
    //     Built-in guests are denied all access.
    //     Anonymous logon is denied all access.
    //     Authenticated users are allowed 
    //     read/write/execute access.
    //     Administrators are allowed full control.
    // Modify these values as needed to generate the proper
    // DACL for your application. 
    TCHAR * szSD = TEXT("D:")       // Discretionary ACL
        TEXT("(D;OICI;GA;;;BG)")     // Deny access to 
        // built-in guests
        TEXT("(D;OICI;GA;;;AN)")     // Deny access to 
        // anonymous logon
        TEXT("(A;OICI;GRGWGX;;;AU)") // Allow 
        // read/write/execute 
        // to authenticated 
        // users
        TEXT("(A;OICI;GA;;;BA)");    // Allow full control 
    // to administrators

    if (NULL == pSA)
        return FALSE;

    return ConvertStringSecurityDescriptorToSecurityDescriptor(
        szSD,
        SDDL_REVISION_1,
        &(pSA->lpSecurityDescriptor),
        NULL);
}



///////////////////////////////////////////////////////////////////////////////
// Given a HANDLE to a file, it's a little tough to get the corresponding file
// name. One way is to use an undocumented NTDDK API. Another is to use a func
// that's only available on Vista. This approach works on NT, 2000, XP, and
// Vista. Code taken from:
//
// http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx
//
///////////////////////////////////////////////////////////////////////////////
BOOL GetFileNameFromHandle(HANDLE hFile, LPTSTR pszFilename, int nLength) 
{
    BOOL bSuccess = FALSE;
    HANDLE hFileMap;

    // Get the file size.
    DWORD dwFileSizeHi = 0;
    DWORD dwFileSizeLo = GetFileSize(hFile, &dwFileSizeHi); 

    if( dwFileSizeLo == 0 && dwFileSizeHi == 0 )
        return FALSE;

    SECURITY_ATTRIBUTES  sa;
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.bInheritHandle = FALSE;

    CreateMyDACL(&sa);

    // Create a file mapping object.
    hFileMap = CreateFileMapping(hFile, 
        &sa, 
        PAGE_READONLY,
        0, 
        1,
        NULL);
    if (!hFileMap)
    {
        int dwError = GetLastError();
        return FALSE;
    }

    if (hFileMap) 
    {
        // Create a file mapping to get the file name.
        void* pMem = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 1);

        if (pMem) 
        {
            if (GetMappedFileName (GetCurrentProcess(), 
                pMem, 
                pszFilename,
                MAX_PATH)) 
            {

                // Translate path with device name to drive letters.
                TCHAR szTemp[BUFSIZE];
                szTemp[0] = '\0';

                if (GetLogicalDriveStrings(BUFSIZE-1, szTemp)) 
                {
                    TCHAR szName[MAX_PATH];
                    TCHAR szDrive[3] = TEXT(" :");
                    BOOL bFound = FALSE;
                    TCHAR* p = szTemp;

                    do 
                    {
                        // Copy the drive letter to the template string
                        *szDrive = *p;

                        // Look up each device name
                        if (QueryDosDevice(szDrive, szName, MAX_PATH))
                        {
                            UINT uNameLen = _tcslen(szName);

                            if (uNameLen < MAX_PATH) 
                            {
                                bFound = _tcsnicmp(pszFilename, szName, 
                                    uNameLen) == 0;

                                if (bFound) 
                                {
                                    // Reconstruct pszFilename using szTempFile
                                    // Replace device path with DOS path
                                    TCHAR szTempFile[MAX_PATH];
                                    StringCchPrintf(szTempFile,
                                        MAX_PATH,
                                        TEXT("%s%s"),
                                        szDrive,
                                        pszFilename+uNameLen);
                                    StringCchCopyN(pszFilename, MAX_PATH+1, szTempFile, _tcslen(szTempFile));
                                }
                            }
                        }

                        // Go to the next NULL character.
                        while (*p++);
                    } while (!bFound && *p); // end of string
                }
            }
            bSuccess = TRUE;
            UnmapViewOfFile(pMem);
        } 

        CloseHandle(hFileMap);
    }

    return(bSuccess);
}

